using B.S.Data.MES.API.Dto.InvoiceDTO;
using B.S.Domain.InvoiceManagement;
using B.S.Domain.基础数据.客户管理;
using B.S.Infratrctrue;
using B.S.Requst;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Data.MES.API.Applications.B.S.KApplications.Query.InvoiceQuery
{
    /// <summary>
    /// 获取销售发票查询处理程序
    /// 处理销售发票的查询逻辑
    /// </summary>
    public class GetSalesInvoiceQueryHandler : IRequestHandler<GetSalesInvoiceQuery, APIRequst<APIPageing<List<SalesInvoiceDTO>>>>
    {
        private readonly IBaseRepository<SalesInvoice> _salesInvoiceRepository;
        private readonly IBaseRepository<SalesInvoiceDetail> _salesInvoiceDetailRepository;
        private readonly IBaseRepository<client> _customerRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="salesInvoiceRepository">销售发票仓储</param>
        /// <param name="salesInvoiceDetailRepository">销售发票明细仓储</param>
        /// <param name="customerRepository">客户仓储</param>
        public GetSalesInvoiceQueryHandler(
            IBaseRepository<SalesInvoice> salesInvoiceRepository,
            IBaseRepository<SalesInvoiceDetail> salesInvoiceDetailRepository,
            IBaseRepository<client> customerRepository)
        {
            _salesInvoiceRepository = salesInvoiceRepository;
            _salesInvoiceDetailRepository = salesInvoiceDetailRepository;
            _customerRepository = customerRepository;
        }

        /// <summary>
        /// 处理获取销售发票列表的查询
        /// </summary>
        /// <param name="request">获取销售发票查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理结果，包含分页的销售发票列表</returns>
        public async Task<APIRequst<APIPageing<List<SalesInvoiceDTO>>>> Handle(GetSalesInvoiceQuery request, CancellationToken cancellationToken)
        {
            try
            {
                // 构建查询
                var query = _salesInvoiceRepository.GetAll()
                    .Where(s => !s.isDel); // 排除已删除的记录

                // 按关键词过滤
                if (!string.IsNullOrEmpty(request.Keyword))
                {
                    query = query.Where(s =>
                        s.InvoiceNo.Contains(request.Keyword) ||
                        s.Remarks.Contains(request.Keyword));
                }

                // 按发票状态过滤
                if (request.InvoiceStatus > -1)
                {
                    query = query.Where(s => s.InvoiceStatus == request.InvoiceStatus);
                }

                // 按客户ID过滤
                if (request.CustomerId > 0)
                {
                    query = query.Where(s => s.CustomerId == request.CustomerId);
                }

                // 按日期范围过滤
                if (request.StartDate.HasValue)
                {
                    query = query.Where(s => s.InvoiceDate >= request.StartDate.Value.Date);
                }
                if (request.EndDate.HasValue)
                {
                    query = query.Where(s => s.InvoiceDate <= request.EndDate.Value.Date.AddDays(1).AddMilliseconds(-1));
                }

                // 计算总记录数
                int totalCount = await query.CountAsync(cancellationToken);

                // 计算总页数
                int totalPage = (totalCount + request.PageSize - 1) / request.PageSize;

                // 执行分页查询
                var salesInvoices = await query
                    .OrderByDescending(s => s.InvoiceId)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 获取相关的客户信息
                var customerIds = salesInvoices.Select(s => s.CustomerId).Distinct().ToList();
                var customers = await _customerRepository.GetListAsync(c => customerIds.Contains(c.CustomerID), cancellationToken);
                var customerDict = customers.ToDictionary(c => c.CustomerID, c => c);

                // 转换为DTO列表
                var salesInvoiceDTOs = new List<SalesInvoiceDTO>();
                foreach (var invoice in salesInvoices)
                {
                    var dto = new SalesInvoiceDTO
                    {
                        InvoiceId = invoice.InvoiceId,
                        InvoiceNo = invoice.InvoiceNo,
                        CustomerId = invoice.CustomerId,
                        CustomerName = invoice.Customer != null ? invoice.Customer.Customername : string.Empty,
                        InvoiceDate = invoice.InvoiceDate,
                        InvoiceStatus = invoice.InvoiceStatus,
                        InvoiceStatusName = GetInvoiceStatusName(invoice.InvoiceStatus),
                        InvoiceAmount = invoice.InvoiceAmount,
                        CreateTime = invoice.CreateTime,
                        CreateName = invoice.CreateName,
                        UpdateTime = invoice.UpdateTime,
                        UpdateName = invoice.UpdateName,
                        Remarks = invoice.Remarks,
                        OrderId = invoice.OrderId
                    };

                    // 获取客户名称（如果数据库中没有存储客户名称）
                    if (string.IsNullOrEmpty(dto.CustomerName) && customerDict.TryGetValue(dto.CustomerId, out var customer))
                    {
                        dto.CustomerName = customer.Customername;
                    }

                    salesInvoiceDTOs.Add(dto);
                }

                // 构建分页结果
                var pageResult = new APIPageing<List<SalesInvoiceDTO>>
                {
                    Total = totalPage,
                    TotalCount = totalCount,
                    Data = salesInvoiceDTOs
                };

                return new APIRequst<APIPageing<List<SalesInvoiceDTO>>>
                {
                    Code = RequstCode.成功,
                    Msg = "查询成功",
                    Data = pageResult
                };
            }
            catch (Exception ex)
            {
                // 记录异常并返回失败结果
                return new APIRequst<APIPageing<List<SalesInvoiceDTO>>>
                {
                    Code = RequstCode.失败,
                    Msg = $"查询失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 获取发票状态名称
        /// </summary>
        /// <param name="status">发票状态值</param>
        /// <returns>发票状态名称</returns>
        private string GetInvoiceStatusName(int status)
        {
            switch (status)
            {
                case 0:
                    return "待开具";
                case 1:
                    return "已开具";
                case 2:
                    return "已作废";
                case 3:
                    return "已红冲";
                default:
                    return "未知";
            }
        }
    }
}